home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Monster Media 1994 #2
/
Monster Media No. 2 (Monster Media)(1994).ISO
/
utils2
/
vynch_2.zip
/
VOYNICH.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1994-06-05
|
57KB
|
1,806 lines
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
#include <dos.h>
#include <dir.h>
#include <bios.h>
#include <direct.h>
#include <alloc.h>
#define HASH_LEN 4096 /* # hash table entries */
#define BUFF_LEN 16384 /* size of disk to buffer */
#define WIPE "VOYNICH ■ VOYNICH ■ VOYNICH ■ VOYNICH ■ VOYNICH ■ VOYNICH ■ "
typedef unsigned char uchar; /* 8 bits, unsigned */
typedef unsigned int uint; /* 16 bits, unsigned */
//===========================================================================
// Globals
uchar *hash_tbl[HASH_LEN]; /* hash table */
uchar inbuff[BUFF_LEN]; /* io buffers */
uchar outbuff[BUFF_LEN];
int curs = 1;
char crypt[] = ":-(▓@"; // encryption stamp
extern int _wscroll = 0; // hold the screen from scrolling
char check[] = "no way in hell are you going to break this cypher!";
char mutate[10000] = "1234567890";
char defaultpth[128];
int defaultdrv;
//===========================================================================
// Function prototypes
int getkey();
void curon();
void curoff();
void showscrn(int flg);
int oops();
char *wrkfile(int typ, int bkgrdclr, int hghclr, int lowclr, int frclr, int bkclr, int txclr);
int cryptit(char *fname);
int ckencrpt(char*);
int menu(char *fname);
long cnvert(char *code);
void warncrypt(char *fname);
void yikes();
int getcode(int flag, char *code, char *fname);
int getfile(char *temp, int typ, int hghclr, int lowclr, int frclr, int bkclr, int txclr);
void sort(char *ptr[], int fg);
void box(int tr, int br, int ls, int rs, int typ);
int edit(int fg, int lm, char *text);
void menudraw(char *ptr[], int a, int b, int c, int d, int z);
int scrlmenu(char *ptr[], int fg, int a, int b, int c, int d, int typ, int hghclr, int lowclr, int frclr, int bkclr, int txclr);
void menudo(char *ptr[], int a, int b, int c, int d, int z, int count, int hghclr, int lowclr, int bkclr, int txclr);
void cgdrv();
void blank();
void do_compress(char *fname, char *compfle);
void do_decompress(char *fname, char *compfle);
int rdc_compress(uchar *inbuff, uint inbuff_len, uchar *outbuff, uchar *hash_tbl[], uint hash_len);
int rdc_decompress(uchar *inbuff, uint inbuff_len, uchar *outbuff);
void wipefle(char *fname);
//===========================================================================
// Function main
void main()
{
int x;
char buf[128]; // buffer to store file reads
*(crypt + 3) = 26;
defaultdrv = getdisk();
strcpy(defaultpth, "X:\\");
defaultpth[0] = 'A' + getdisk();
getcurdir(0, defaultpth + 3);
if(strcmp(mutate, "1234567890") == 0)
x = oops();
//**********************************************************
//*** this is for testing purposes only
// srand(1956);
// for(x = 1; x < 10000; x++)
// {
// count = random(254) + 1;
// mutate[x] = count;
// }
//**********************************************************
while(x)
{
strcpy(buf, wrkfile(2, 1, 15, 1, 11, 3, 0));
if(strlen(buf))
x = cryptit(buf);
else
x = 0;
if(x == 4)
x = 0;
}
window(1, 1, 80, 25);
setdisk(defaultdrv);
chdir(defaultpth);
curon();
textcolor(7);
textbackground(0);
clrscr();
}
//===========================================================================
//*** function wrkfile: get file and path to work on the integer arguments
//*** are as follows ==> typ: the box line type
//*** ==> bkgrdclr: the overall screen color
//*** ==> highclr: the text color of the highlight bar &
//*** path label
//*** ==> lowclr: the background color of highlight bar
//*** ==> frclr: foreground color of box
//*** ==> bkclr: background color of box
//*** ==> txclr: color of text inside box
char *wrkfile(int typ, int bkgrdclr, int hghclr, int lowclr, int frclr, int bkclr, int txclr)
{
int x = 1;
char buf[128];
char fname[128];
char *gotptr;
while(x) // for-ever
{
*(fname + 0) = NULL;
window(1, 1, 80, 25);
showscrn(1);
window(1, 3, 80, 23);
textbackground(bkgrdclr);
clrscr();
curoff();
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
//cprintf("Coreleft is: %lu bytes\n", (unsigned long) coreleft());
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
while(x = getfile(fname, typ, hghclr, lowclr, frclr, bkclr, txclr))
if(x) // user picked directory
{
*(buf + 0) = NULL;
strcpy(buf, fname);// fname holds new dir
chdir(buf); // change directory
textbackground(bkgrdclr);
window(1, 1, 80, 25);
showscrn(1);
window(1, 3, 80, 23);
textbackground(bkgrdclr);
clrscr();
}
}
curon();
window(1, 1, 80, 25);
gotptr = fname;
return gotptr;
}
//===========================================================================
//*** function cryptit: get the job done
int cryptit(char *fname)
{
int x, y, flag;
char buf;
char compfle[128];
char inbuf[BUFSIZ]; // buffer input
char outbuf[BUFSIZ]; // buffer output
char *code = new char[6]; // user supplied key
char *control = new char[6]; // used to check crypt stamp
char *offptr = new char[6];
char *passwrd = new char[51];
long key; // derived from code -- seeds srand
FILE *in, *out;
strcpy(passwrd, check);
strcpy(compfle, fname);
if(*(strstr(compfle, ".")) != NULL)
*(strstr(compfle, ".")) = NULL;
strcat(compfle, ".$$$");
flag = menu(fname);
if(flag > 2)
{
delete code;
delete control;
delete offptr;
delete passwrd;
return flag;
}
flag = getcode(flag, code, fname);
if(flag > 2)
{
delete code;
delete control;
delete offptr;
delete passwrd;
return flag;
}
key = cnvert(code);
sprintf(offptr, "%u\0", key);
switch(flag)
{
case 2: // user selected -- decode file
gotoxy(57, 13); // confirm processing
cprintf("decoding...");
in = fopen(fname, "rb");
setbuf(in, inbuf);
out = fopen("e$n$c$r$.tmp", "wb");
setbuf(out, outbuf);
x = 0;
while(fread(&buf, sizeof(char), 1, in))
{
*(control + x) = buf; // this loop reads in first five
x++; // bytes of file to check and
if(x == 5) // make sure that it is encrypted
break; // by this program.
}
*(control + x) = NULL;
if(strcmp(control, crypt) != 0)
// oops! no encryption stamp!
{
fclose(out);
remove("e$n$c$r$.tmp");
warncrypt(fname);
return 3;
}
break;
case 1: // user selected file encryption
gotoxy(57, 13); // confirm processing
cprintf("compressing...");
do_compress(fname, compfle);
wipefle(fname);
remove(fname); // file are the same process -- it
rename(compfle, fname); // reverses itself
gotoxy(57, 13); // confirm processing
cprintf("encrypting... ");
in = fopen(fname, "rb");
setbuf(in, inbuf);
out = fopen("e$n$c$r$.tmp", "wb");
setbuf(out, outbuf);
fwrite(crypt, sizeof(char), 5, out); // write encryption stamp
y = 0;
for(x = 0; x < 50; x++)
{
if(y == 5) y = 0;
*(passwrd + x) = *(passwrd + x) ^ *(offptr + y);
y++;
}
fwrite(passwrd, sizeof(char), 50, out);
break;
}
//***********************************************************
//*** encryption/decryption routine
x = 0;
y = 0;
if(flag == 2)
{
fread(passwrd, sizeof(char), 50, in);
for(x = 0; x < 50; x++)
{
if(y == 5) y = 0;
*(passwrd + x) = *(passwrd + x) ^ *(offptr + y);
y++;
}
*(passwrd + 50) = NULL;
if(strcmp(check, passwrd) != 0)
{
yikes();
return 3;
}
}
x = 0;
y = 0;
while(fread(&buf, sizeof(char), 1, in))
{
if(x == 5) x = 0;
if(y == 10000) y = 0;
buf = buf ^ (*(mutate + y) ^ *(offptr + x));
fwrite(&buf, sizeof(char), 1, out);
y++;
x++;
}
fcloseall(); // the encryption and decoding of the
wipefle(fname);
remove(fname); // file are the same process -- it
rename("e$n$c$r$.tmp", fname); // reverses itself
if(flag == 2)
{
gotoxy(57, 13); // confirm processing
cprintf("decompressing...");
strcpy(compfle, fname);
if(*(strstr(compfle, ".")) != NULL)
*(strstr(compfle, ".")) = NULL;
strcat(compfle, ".$$$");
do_decompress(fname, compfle);
fcloseall(); // the encryption and decoding of the
remove(fname); // file are the same process -- it
rename(compfle, fname); // reverses itself
}
delete code;
delete control;
delete offptr;
delete passwrd;
return 3;
}
//===========================================================================
//*** function yikes: this is the wrong passwrd folks
void yikes()
{
int x;
char buf = 65;
fcloseall();
remove("e$n$c$r$.tmp");
curoff();
putch(7); // sound bell and abort process
textcolor(11);
textbackground(4);
for(x = 7; x < 14; x++)
{
gotoxy(15, x);
cprintf(" ");
}
box(7, 13, 15, 65, 2);
textcolor(14);
gotoxy(17, 9);
cprintf("!! Y I K E S !!");
gotoxy(17, 10);
cprintf("Wrong code! Try again, and good luck.");
gotoxy(17, 11);
cprintf("Press Esc to continue.");
while(buf != 27)
buf = getch();
}
//===========================================================================
//*** function ckencrpt: check to see if file is already encrypted
int ckencrpt(char* fptr)
{
FILE *in;
int x;
char buf = 66;
char *control = new char[6];
in = fopen(fptr, "rb");
x = 0;
while(fread(&buf, sizeof(char), 1, in))
{
*(control + x) = buf; // this loop reads in first five
x++; // bytes of the file
if(x == 5)
break;
}
fclose(in);
*(control + x) = NULL;
if(strcmp(control, crypt) == 0) // check for match to stamp
{
delete control;
return 1; // return true -- file encrypted
}
else
{
delete control;
return 0; // return false -- file not encrypted
}
}
//===========================================================================
//*** function warncrypt: holler if decode attempt on unencrypted file
void warncrypt(char *fname)
{
int x;
char buf = 65;
curoff();
putch(7); // sound bell and abort process
textcolor(11);
textbackground(4);
for(x = 7; x < 14; x++)
{
gotoxy(15, x);
cprintf(" ");
}
box(7, 13, 15, 65, 2);
textcolor(14);
gotoxy(17, 9);
cprintf("!! %s", fname);
gotoxy(17, 10);
cprintf("This file was not encrypted by Voynich.");
gotoxy(17, 11);
cprintf("Press Esc to continue.");
while(buf != 27)
buf = getch();
}
//===========================================================================
//*** function cnvert: convert user supplied character code to a long
long cnvert(char *code)
{
char buffer[20];
sprintf(buffer, "%d%d%d%d%d", code[0], code[1], code[2], code[3], code[4]);
return (atol(buffer));
}
//===========================================================================
//*** function wipefle:
void wipefle(char *fname)
{
FILE *in;
long flbyte;
struct ffblk ffblk;
findfirst(fname, &ffblk, 0);
in = fopen(fname, "r+b");
for(flbyte = 1; flbyte <= (ffblk.ff_fsize/sizeof(WIPE)); flbyte++)
fwrite(WIPE, sizeof(WIPE), 1, in);
flbyte = ffblk.ff_fsize - (ffblk.ff_fsize/sizeof(WIPE)) * sizeof(WIPE);
if(flbyte)
fwrite(WIPE, sizeof(char), flbyte, in);
fclose(in); // the encryption and decoding of the
}
//===========================================================================
//*** function getcode:
int getcode(int flag, char *code, char *fname)
{
int x;
window(1, 1, 80, 25);
clrscr();
showscrn(3);
window(1, 3, 80, 23);
textbackground(1);
clrscr();
window(5, 10, 75, 17);
textbackground(3);
clrscr();
window(1, 3, 80, 23);
box(8, 16, 5, 75, 2);
textcolor(4);
gotoxy(10, 11);
if(flag == 2)
cprintf("DECODE the file --> %s", fname);
else
cprintf("ENCRYPT the file --> %s", fname);
curon();
gotoxy(10, 13);
textcolor(15);
cprintf("The encryption code must be 5 characters long: ");
//textcolor(12);
*(code + 0) = NULL;
x = 1;
while(x) // loop to get user supplied key
{
x = edit(5, 5, code); // call line edit for input
if(x == - 1) // user pressed Esc -- abort program
return 4;
if(strlen(code) == 5) // key is proper length
x = 0; // release loop
else // key is too short!
{
putch(7); // warn user and reset
gotoxy(57, 13);
cprintf(" ");
*(code + 0) = NULL;
gotoxy(57, 13);
}
}
return flag;
}
//===========================================================================
//*** function getkey: use DOS interrupt to get keypress values
int getkey()
{
union REGS r;
r.h.ah = 0;
return int86(0x16, &r, &r);
}
//===========================================================================
//*** function get file: get files in current directory
int getfile(char *temp, int typ, int hghclr, int lowclr, int frclr, int bkclr, int txclr)
{
struct ffblk ffblk; // structure to hold file data
int done, z, y = 0, x = 0; // counters
char path[128];
char buffer [25]; // string to hold selected file name
char **array = new char *[1000]; // read up to 1000 files in directory
*(buffer + 0) = NULL;
curoff();
x = 0;
done = findfirst("*.*", &ffblk, FA_DIREC);
// find first file in path
while(!done) // loop to read in rest of files
{
if(ffblk.ff_attrib == 16)
{
if(strcmp(ffblk.ff_name, ".") != 0)
{
*(array + x) = new char [strlen(ffblk.ff_name) + 2];
sprintf(buffer, "\\%s\0", ffblk.ff_name);
strcpy(*(array + x), buffer);
// put files into array
}
else
x--;
}
else
{
//*(array + x) = new char [strlen(ffblk.ff_name) + 13];
*(array + x) = new char [28];
sprintf(buffer, "%-12s %9lu\0", ffblk.ff_name, ffblk.ff_fsize);
strcpy(*(array + x), buffer);
// put files into array
}
done = findnext(&ffblk);
x++;
}
if(x)
{
sort(array, x); // sort the file list
if(x + 2 < 17) // dynamically size file display box
done = x + 3;
else
done = 17;
strcpy(path, "X:\\");
// fill string with form of response: X:\
path[0] = 'A' + getdisk(); // replace X with current drive letter
getcurdir(0, path + 3);
// fill rest of string with current directory
textcolor(hghclr);
gotoxy(7, done + 3);
//printf("heap left: %lu bytes\n", farcoreleft());
cprintf("Path %c%c%c %s", 196, 196, 16, path);
gotoxy(41, 3);
cprintf("%c%c%c select a file to process", 17, 196, 196);
y = scrlmenu(array, x, 2, done, 2, 35, typ, hghclr, lowclr, frclr, bkclr, txclr);
// call scroll box and get file
if(y == - 1) // user pressed Esc ── abort and exit
{
*(temp + 0) = NULL;
return 0; // end program
}
if(y > - 1)
{
strcpy(buffer, *(array + y));
*(strstr(buffer, " ") + 0) = NULL;
// file to open is in buffer
if(*(path + strlen(path) - 1) == 92)
*(path + strlen(path) - 1) = NULL;
if(*(buffer + 0) == 92)
sprintf(temp, "%s%s", path, buffer);
else
sprintf(temp, "%s\\%s", path, buffer);
}
}
else
{
blank();
y = - 2;
}
for(z = 0; z < x; z++) // deallocate heap
delete *(array + z);
delete array;
// by temp
if(y == - 2) // need to refresh display
{
done = 1;
*(temp + 0) = NULL;
}
else
if(*(buffer + 0) == 92) done = 1; else done = 0;
return done;
}
//===========================================================================
//*** function showscrn: opening screen
void showscrn(int flg)
{
int x;
textcolor(11);
textbackground(3);
clrscr();
gotoxy(1, 2);
cprintf(" %c%c%c%c V O Y N I C H %c%c%c%c", 240, 240, 240, 240, 240, 240, 240, 240);
switch(flg)
{
case 1:
gotoxy(12, 24);
cprintf("[F10] change drive %c%c%c%c select [Esc] quit ", 17, 196, 196, 217);
break;
case 2:
break;
case 3:
gotoxy(20, 24);
cprintf("Type your encryption key and press ENTER");
break;
}
for(x = 1; x < 81; x++)
{
gotoxy(x, 1);
cprintf("%c", 223);
gotoxy(x, 25);
cprintf("%c", 220);
}
}
//===========================================================================
//*** function menu:
int menu(char *fname)
{
int x;
char buf = 66;
textcolor(11);
gotoxy(1, 24);
cprintf(" Press the boxed key to make a selection ");
window(1, 3, 80, 23);
textbackground(1);
clrscr();
x = ckencrpt(fname); // check file to see if encrypted
if(x) // file is already encrypted
{
putch(7); // warn the user of existing encoding
textcolor(11);
textbackground(4);
for(x = 13; x < 19; x++)
{
gotoxy(52, x);
cprintf(" ");
}
box(13, 18, 52, 77, 2);
textcolor(14);
gotoxy(56, 15);
cprintf("NOTE! This file is");
gotoxy(56, 16);
cprintf("already encrypted.");
}
textbackground(5);
textcolor(11);
gotoxy(10, 3);
cprintf(" ");
gotoxy(10, 4);
cprintf(" <1> ");
gotoxy(10, 5);
cprintf(" ");
gotoxy(10, 7);
cprintf(" ");
gotoxy(10, 8);
cprintf(" <2> ");
gotoxy(10, 9);
cprintf(" ");
gotoxy(10, 11);
cprintf(" ");
gotoxy(10, 12);
cprintf(" <3> ");
gotoxy(10, 13);
cprintf(" ");
gotoxy(10, 15);
cprintf(" ");
gotoxy(10, 16);
cprintf(" <Esc> ");
gotoxy(10, 17);
cprintf(" ");
textbackground(1);
textcolor(15);
gotoxy(19, 4);
cprintf("ENCRYPT the file %s", fname);
gotoxy(19, 8);
cprintf("DECODE the file %s", fname);
gotoxy(19, 12);
cprintf("OOPS! wrong file, try again.");
gotoxy(19, 16);
cprintf("NOPE. just quit.");
curoff();
// loop to get user menu choice
while(buf != 49 && buf != 50 && buf != 51 && buf != 27)
buf = getch();
switch(buf)
{
case 49: // user pressed 1 -- encrypt file
return 1;
case 50: // user pressed 2 -- decode file
return 2;
case 51: // user pressed 3 -- oops wrong file
return 3;
case 27: // user pressed Esc -- abort program
return 4;
}
return 4;
}
//===========================================================================
//*** function blank:
void blank()
{
int x;
char *stuff = new char[10];
textcolor(11);
textbackground(3);
box(10, 16, 40, 76, 2);
for(x = 11; x < 16; x++)
{
gotoxy(41, x);
cprintf(" ");
}
textcolor(15);
gotoxy(42, 12);
cprintf("Disk is empty.");
gotoxy(42, 14);
cprintf("Enter the new drive letter: ");
curon();
*(stuff + 0) = NULL;
x = edit(5, 1, stuff);
curoff();
if(x == 2)
{
if(*(stuff + 0) > 96)
*(stuff + 0) = *(stuff + 0) - 32;
x = *(stuff + 0);
x -= 64;
if(_chdrive(x) == - 1)
putch(7);
}
delete stuff;
}
//===========================================================================
//*** Function sort: a standard shell sort algorithm. array is pointer array
//*** to strings, fg is the count.
//*** NOTE! strings in the array better be null terminated!
void sort(char *ptr[], int fg)
{
int x = 2;
int y = fg;
int z;
int t;
int done;
char *temp1;
x = fg / 2;
while(x >= 1)
{
for(y = 0; y < x; y++)
{
for(z = y; z < (fg - x); z += x)
{
t = z;
temp1 = *(ptr + (z + x));
done = 0;
while(t >= y && done == 0)
{
if(strcmp(temp1, *(ptr + t)) > 0)
done = 1;
else
{
*(ptr + (t + x)) = *(ptr + t);
t -= x;
}
}
*(ptr + (t + x)) = temp1;
}
}
x = x / 2;
}
}
//===========================================================================
//*** function box: draw a double line box on the screen
//*** the four intergers are the coordinates of the four corners.
//*** tr = top row ── br = bottom row ── ls = left side ── rs = right side
void box(int tr, int br, int ls, int rs, int typ)
{
int x;
unsigned char lftop;
unsigned char rgtop;
unsigned char lfbtm;
unsigned char rgbtm;
unsigned char hzlin;
unsigned char vtlin;
switch(typ)
{
case 1: // double line box
lftop = 201;
rgtop = 187;
lfbtm = 200;
rgbtm = 188;
hzlin = 205;
vtlin = 186;
break;
case 2:
lftop = 218;
rgtop = 191;
lfbtm = 192;
rgbtm = 217;
hzlin = 196;
vtlin = 179;
break;
case 3:
lftop = 214;
rgtop = 183;
lfbtm = 211;
rgbtm = 189;
hzlin = 196;
vtlin = 186;
break;
case 4:
lftop = 213;
rgtop = 184;
lfbtm = 212;
rgbtm = 190;
hzlin = 205;
vtlin = 179;
break;
}
gotoxy(ls, tr); // draw in the box corners
cprintf("%c", lftop);
gotoxy(rs, tr);
cprintf("%c", rgtop);
gotoxy(ls, br);
cprintf("%c", lfbtm);
gotoxy(rs, br);
cprintf("%c", rgbtm);
for(x = tr + 1; x <= br - 1; x++) // loop to draw in box sides
{
gotoxy(ls, x);
cprintf("%c", vtlin);
gotoxy(rs, x);
cprintf("%c", vtlin);
}
for(x = ls + 1; x <= rs - 1; x++) // loop to draw in box top & bottom
{
gotoxy(x, tr);
cprintf("%c", hzlin);
gotoxy(x, br);
cprintf("%c", hzlin);
}
textcolor(0);
for(x = tr + 1; x <= br; x++) // loop to draw in box shadow
{
gotoxy(rs + 1, x);
cprintf("%c", 219);
}
for(x = ls + 1; x <= rs + 1; x++) // loop to draw in box shadow
{
gotoxy(x, br + 1);
cprintf("%c", 219);
}
}
//===========================================================================
//*** function edit: a single line text input function using three parameters.
//*** the variable fg can be used to both control the function when called as
//*** well as return a value for subsequent action. The variable lm sets the
//*** allowable length of the input string. The string text will display in the
//*** input field upon call as well as return the user's input data. (!! text
//*** is a pointer to a string.) This function requires the function getkey()
int edit(int fg, int lm, char *text)
{
int r; // anchored cursor position
int q; // limit counter
int z; // use as for loop counter
int x; // cursor position
int y; // cursor position
int flg; // internal string position
int code = 1; // scan code flag
char kbd; // key press value
char temp[45]; // temporary string buffer
int pd = 1; // initialize loop control variables
int ins = 1; // default with Ins on
union scan // union to hold keyboard scan code
{
int c;
char ch[2];
} sc;
r = wherex(); // constant for left cursor position
q = strlen(text); // set limit counter from string sent
cprintf("%s", text); // display any sent text
x = wherex(); // get the current cursor position
y = wherey();
do // main loop -- take input until exit
{
gotoxy(x, y);
while(kbhit() == 0); // holding loop waits for key press
sc.c = getkey(); // get the keyboard scan code
if(*(sc.ch + 0) == 0) // this is a function or cursor key
{
code = 0; // set scan code flag
kbd = *(sc.ch + 1); // read in key press value
}
else // this is an alphanumeric key
{
code = 1; // set scan code flag
kbd = *(sc.ch + 0); // read in key press value
}
if(code) // key is alpha-numeric or ESC/CR
{
switch(kbd)
{
case 27: // user pressed ESC
pd = 0; // release loop
fg = - 1; // set return flag
break;
case 13: // user pressed Enter
pd = 0; // release loop
fg = 2; // set return flag
break;
case 8: // user pressed bkspace
if(x > r) // bkspace is valid
{
if(x < r + q) // !! in middle of string
{
code = (r + q) - x;
// get position in string
pd = 0; // read string from cursor
for(z = (q - code); z != q; z++)
// to end & store
{
flg = *(text + z);
// in temp string
*(temp + pd) = flg;
++pd;
}
*(temp + pd) = '\0';
*(text + (q - code) - 1) = NULL;
// remove end chr
strcat(text, temp);
// re-attach string end
gotoxy(--x, y);
cprintf("%s%c", temp, 32);
// redraw screen
--q; // decrement strlen counter
pd = 1; // put pd back after use!
}
else // at end of the string
{
putch(8);// take care of display
putch(32);
putch(8);
*(text + strlen(text) - 1) = NULL;
// truncate string
--q; // decrement strlen counter
--x; // decrement cur positon
}
}
break;
default: // valid key press
if(x < r + q) // !! middle of string
{
if(ins) // Ins mode is on
{
if(q < lm)
// limit is not reached
{
code = (r + q) - x;
pd = 0;
for(z = (q - code); z != q; ++z)
{
flg = *(text + z);
*(temp + pd) = flg;
++pd;
}
*(temp + pd) = '\0';
// see bkspace
*(text + (q - code)) = kbd;
// process for
*(text + (q - code) + 1) = '\0';
// notes on this
strcat(text, temp);
// section
putch(kbd);
cprintf("%s", temp);
pd = 1;
++q;
++x;
}
}
else // Ins mode is off
{
code = (r + q) - x;
pd = 0;
for(z = (q - code + 1); z != q; ++z)
{
flg = *(text + z);
*(temp + pd) = flg;
++pd;
} // see bkspace process
*(temp + pd) = '\0';
// for notes
*(text + (q - code)) = kbd;
*(text + (q - code) + 1) = '\0';
strcat(text, temp);
putch(kbd);
pd = 1;
++x;
}
}
else // at end of string
{
if(q < lm)
{
putch(kbd);
sprintf(temp, "%s%c", text, kbd);
// here's another
strcpy(text, temp);
// way to splice
++q; // the ends of two
++x; // strings
}
}
}
}
else // function or cursor control key
{
switch(kbd)
{
case 82: // user toggled Ins
if(ins) // set Ins flag as indicated
ins = 0; // if on, turn off
else
ins = 1; // if off, turn on
break;
case 72: // user pressed up arrow
if(fg < 5)
{
fg = 1; // set return flag
pd = 0; // release loop
}
break;
case 80: // user pressed down arrow
if(fg < 5)
{
fg = 2; // set return flag
pd = 0; // release loop
}
break;
case 75: // user pressed left arrow
if(x > r) // key press is valid so
--x; // decrement cursor counter
break;
case 77: // user pressed right arrow
if(x < r + q) // key press is valid
++x; // increment cursor counter
break;
case 71: // user pressed home
x = r; // reset cursor counter
break;
case 79: // user pressed end
x = r + strlen(text);
// reset cursor counter
break;
case 83: // user pressed del
if(x < r + q) // key press is valid
{
code = (r + q) - x;
pd = 0;
for(z = (q - code + 1); z != q; ++z)
{
flg = *(text + z);
*(temp + pd) = flg;
++pd;
} // see bkspace process for
*(temp + pd) = '\0';
// notes on this routine
*(text + (q - code)) = '\0';
strcat(text, temp);
cprintf("%s%c", temp, 32);
pd = 1;
--q;
}
break;
case 68: // user pressed [F10]
if(fg < 5)
{
fg = 3;
pd = 0;
}
}
}
} while(pd != 0);
return fg; // set return flag
}
//===========================================================================
//*** function scrlmenu: draws a box on screen, displays the menu selections,
//*** and allows the user to scroll through and make a selection. the var
//*** fg is the number of items in the array and the vars a thru d are the
//*** screen coordinates for the menu box. This function calls the functions
//*** getkey(), curon(), curoff(), menudo(), and menudraw()
int scrlmenu(char *ptr[], int fg, int a, int b, int c, int d, int typ, int hghclr, int lowclr, int frclr, int bkclr, int txclr)
{
int pd; // loop control flag
char kbd; // user keypress
int z = 0; // offset counter
int count = 0; // menu counter
int code = 0; // keyboard scan code
int util; // utilities choice
char buffer[60]; // hold system command line
union scan // union to hold keyboard scan code
{
int c;
char ch[2];
} sc;
curoff(); // turn cursor off
textcolor(frclr);
textbackground(bkclr);
box(a, b, c, d, typ); // draw a box for the menu
textcolor(0);
menudraw(ptr, a, b, c, d, z); // draw the menu items
menudo(ptr, a, b, c, d, z, count, hghclr, lowclr, bkclr, txclr);
pd = 1; // loop control flag
while(pd) // loop allows user to move selection
{
while(kbhit() == 0); // holding loop waits for key press
sc.c = getkey(); // get the keyboard scan code
if(*(sc.ch + 0) == 0) // this is a function or cursor key
{
code = 1; // set scan code flag
kbd = *(sc.ch + 1); // read in key press value
}
else // this is an alphanumeric key
{
code = 0; // set scan code flag
kbd = *(sc.ch + 0); // read in key press value
}
if(code) // user pressed non-alpha key
{
switch(kbd)
{
case 72: // user pressed up arrow
--count; // decrement menu counter
if(count < 0) // already at top
{
count = fg - 1;
// roll over to bottom
if(fg > (b - a) - 1)
// this mess allows
{
// for the possibility
if(fg >= (b - a - 1) * 2)
{
z = (b - a - 1);
// that the menu items
z += (fg - (z * 2));
// number more or less
} // than will fit box
else
z = fg - (b - a - 1);
}
else
z = 0;
menudo(ptr, a, b, c, d, z, count, hghclr, lowclr, bkclr, txclr);
// place highlight
}
else // not yet at top so move up one
{
if(wherey() == a + 1)
z -= 1;
if(z < 0)
z = 0;
menudo(ptr, a, b, c, d, z, count, hghclr, lowclr, bkclr, txclr);
// place highlight
}
break;
case 80: // user pressed down arrow
++count; // increment menu counter
if(count == fg) // already at bottom of list
{
count = 0; // roll over to top
z = 0;
menudo(ptr, a, b, c, d, z, count, hghclr, lowclr, bkclr, txclr);
// place highlight
}
else // not yet at bottom of list
{
if(wherey() == b - 1)
z += 1;
menudo(ptr, a, b, c, d, z, count, hghclr, lowclr, bkclr, txclr);
// place highlight
}
break;
//case 67:
//return - 2;
case 68:
cgdrv();
return - 2;
}
}
else // user pressed alph-numeric
switch(kbd)
{
case 13: // user pressed Enter
if(ptr[count][0] == 4)
{
for(util = 0; util < strlen(*(ptr + count)) - 2; util++)
ptr[count][util] = ptr[count][util + 2];
ptr[count][util] = NULL;
}
pd = 0; // set exit
break;
case 27: // user pressed Esc
pd = 0; // set loop control to exit
fg = - 1; // set return flag to abort
break;
case 32:
if(c == 35)
break;
if(ptr[count][0] == 4)
{
for(util = 0; util < strlen(*(ptr + count)) - 2; util++)
ptr[count][util] = ptr[count][util + 2];
ptr[count][util] = NULL;
}
else
{
if(*(ptr + count)[0] != 92)
{
sprintf(buffer, "%c %s", 4, *(ptr + count));
strcpy(*(ptr + count), buffer);
}
else
putch(7);
}
gotoxy(7, wherey());
textcolor(15); // set highlight bar color
textbackground(7);
cprintf(" %s", *(ptr + count));
textcolor(7); // put color back
textbackground(0);
++count; // increment menu counter
if(count == fg) // already at bottom of list
{
count = 0; // roll over to top
z = 0;
menudo(ptr, a, b, c, d, z, count, hghclr, lowclr, bkclr, txclr);
// place highlight
}
else // not yet at bottom of list
{
if(wherey() == b - 1)
z += 1;
menudo(ptr, a, b, c, d, z, count, hghclr, lowclr, bkclr, txclr);
// place highlight
}
break;
default: // process any alpha key to scroll box
if(kbd > 96)
kbd = kbd - 32;
// all lower case
for(code = 0; code <= fg; code++)
// loop through array
{
if(kbd == ptr[code][0])
// find first element
{
// where first letter
count = code;
// matches keypress
if(count > (b - a) - 2)
z = count - ((b - a) - 2);
else
z = 0;
menudo(ptr, a, b, c, d, z, count, hghclr, lowclr, bkclr, txclr);
// place mark
break;
}
}
break;
}
}
if(fg > - 1)
fg = count; // set return flag
//curon();
return fg; // return user selection
}
//===========================================================================
//*** function menudraw: draws the items inside the menu box
void menudraw(char *ptr[], int a, int b, int c, int d, int z)
{
char temp[81];
int offset;
int q;
int x;
for(x = z; x != z + ((b - a) - 1); ++x)
// loop to draw in menu items
{
offset = (d - c - 5 - strlen(*(ptr + x)));
for(q = 0; q != offset; ++q) // loop to load temp with blanks
*(temp + q) = 32; // temp fills in the balance of
*(temp + q) = '\0'; // the box with spaces
gotoxy(c + 1, (a + 1) + x - z);
cprintf(" %s%s", *(ptr + x), temp);
}
}
//===========================================================================
//*** function menudo places the highlight on the menu selection
void menudo(char *ptr[], int a, int b, int c, int d, int z, int count, int hghclr, int lowclr, int bkclr, int txclr)
{
char temp[81];
int x;
int offset = (d - c - 5 - strlen(*(ptr + count)));
menudraw(ptr, a, b, c, d, z); // 1st re-draw menu items
for(x = 0; x != offset; ++x) // loop to load temp with blanks
*(temp + x) = 32;
*(temp + x) = '\0';
textcolor(hghclr); // set highlight bar color
textbackground(lowclr);
gotoxy(c + 1, (a + 1) + count - z);
// draw highlighted choice
cprintf(" %s%s", *(ptr + count), temp);
textcolor(txclr); // put color back
textbackground(bkclr);
}
//===========================================================================
//*** function cgdrv:
void cgdrv()
{
int x;
char *stuff = new char[10];
textcolor(11);
textbackground(3);
box(11, 15, 40, 75, 2);
for(x = 12; x < 15; x++)
{
gotoxy(41, x);
cprintf(" ");
}
textcolor(15);
gotoxy(42, 13);
cprintf("Enter the new drive letter: ");
curon();
*(stuff + 0) = NULL;
x = edit(5, 1, stuff);
curoff();
if(x == 2)
{
if(*(stuff + 0) > 96)
*(stuff + 0) = *(stuff + 0) - 32;
x = *(stuff + 0);
x -= 64;
if(_chdrive(x) == - 1)
putch(7);
}
textbackground(7);
for(x = 9; x < 16; x++)
{
gotoxy(38, x);
cprintf(" ");
}
textcolor(7);
textbackground(0);
delete stuff;
}
//===========================================================================
//*** function cursor off: turns the damn cursor off!
void curoff()
{
static union REGS inregs, outregs;
if(curs)
{
inregs.h.ah = 1; // load registers
inregs.h.ch = 0x20;
inregs.h.cl = 0;
int86(0x10, &inregs, &outregs);
// DOS call turns cursor off
curs = 0; // set cursor flag
}
}
//===========================================================================
//*** function cursor on: turns the cursor back on
void curon()
{
static union REGS inregs, outregs;
if(!curs)
{
inregs.h.ah = 1; // load registers
inregs.h.ch = 6; // !! will need to adjust this to
inregs.h.cl = 7; // handle color and mono monitors !!
int86(0x10, &inregs, &outregs);
// DOS call turn cursor on
curs = 1; // set cursor flag
}
}
//==========================================================================
//*** function oops: not installed! default out
int oops()
{
char buf;
putch(7);
showscrn(2);
window(1, 3, 80, 23);
textcolor(15);
textbackground(1);
curoff();
clrscr();
window(5, 5, 75, 20);
cprintf("N O T E:\r\n");
cprintf("~~~~~~~~\r\n\n");
cprintf("This copy of Voynich has not been initialized. Until you run the\r\n");
cprintf("initialization program, Voynich will default to this screen and then\r\n");
cprintf("exit.\r\n\n");
cprintf("Before you initialize Voynich, read through the file README!.NOW.\r\n");
cprintf("If you ignore the information in the README!.NOW file, you could\r\n");
cprintf("make a costly mistake.\r\n\n");
textcolor(14);
cprintf("Press Esc to exit to DOS.");
while(buf != 27)
buf = getch();
return 0;
}
void do_compress(char *fname, char *compfle)
{
int bytes_read;
int compress_len;
FILE *infile, *outfile;
infile = fopen(fname, "rb");
outfile = fopen(compfle, "wb");
/* read infile BUFF_LEN bytes at a time */
while((bytes_read = fread(inbuff, 1, BUFF_LEN, infile)) > 0)
{
/* compress this load of bytes */
compress_len = rdc_compress(inbuff, bytes_read, outbuff, hash_tbl, HASH_LEN);
/* write length of compressed buffer */
if(fwrite(&compress_len, sizeof(int), 1, outfile) != 1)
exit(1);
/* check for negative length indicating the
buffer could not be compressed */
if(compress_len < 0)
compress_len = 0 - compress_len;
/* write the buffer */
if(fwrite(outbuff, compress_len, 1, outfile) != 1)
exit(1);
/* we're done if less than full buffer was read */
if(bytes_read != BUFF_LEN)
break;
}
/* add trailer to indicate end of file */
compress_len = 0;
if(fwrite(&compress_len, sizeof(int), 1, outfile) != 1)
exit(1);
fcloseall();
}
void do_decompress(char *fname, char *compfle)
{
int block_len;
int decomp_len;
FILE *infile, *outfile;
infile = fopen(fname, "rb");
outfile = fopen(compfle, "wb");
/* read infile BUFF_LEN bytes at a time */
for(;;)
{
if(fread(&block_len, sizeof(int), 1, infile) != 1)
exit(1);
/* check for end-of-file flag */
if(block_len == 0)
return;
if(block_len < 0) /* copy uncompressed chars */
{
decomp_len = 0 - block_len;
if(fread(outbuff, decomp_len, 1, infile) != 1)
exit(1);
}
else /* decompress this buffer */
{
if(fread(inbuff, block_len, 1, infile) != 1)
exit(1);
decomp_len = rdc_decompress(inbuff, block_len,
outbuff);
}
/* and write this buffer outfile */
if(fwrite(outbuff, decomp_len, 1, outfile) != 1)
exit(1);
}
}
/* from C Users Journal 10/92
* COMPRS.C - Ross Data Compression (RDC)
* compress function
*
* Written by Ed Ross, 1/92
*
* compress inbuf_len bytes of inbuff into outbuff
* using hash_len entries in hash_tbl.
*
* return length of outbuff, or "0 - inbuff_len"
* if inbuff could not be compressed. */
//#include <string.h>
typedef unsigned char uchar; /* 8 bits, unsigned */
typedef unsigned int uint; /* 16 bits, unsigned */
int rdc_compress(uchar *inbuff, uint inbuff_len, uchar *outbuff, uchar *hash_tbl[], uint hash_len)
{
uchar *in_idx = inbuff;
uchar *inbuff_end = inbuff + inbuff_len;
uchar *anchor;
uchar *pat_idx;
uint cnt;
uint gap;
uint c;
uint hash;
uint *ctrl_idx = (uint *) outbuff;
uint ctrl_bits;
uint ctrl_cnt = 0;
uchar *out_idx = outbuff + sizeof(uint);
uchar *outbuff_end = outbuff + (inbuff_len - 48);
/* skip the compression for a small buffer */
if(inbuff_len <= 18)
{
memcpy(outbuff, inbuff, inbuff_len);
return 0 - inbuff_len;
}
/* adjust # hash entries so hash algorithm can
use 'and' instead of 'mod' */
hash_len--;
/* scan thru inbuff */
while(in_idx < inbuff_end)
{
/* make room for the control bits
and check for outbuff overflow */
if(ctrl_cnt++ == 16)
{
*ctrl_idx = ctrl_bits;
ctrl_cnt = 1;
ctrl_idx = (uint *) out_idx;
out_idx += 2;
if(out_idx > outbuff_end)
{
memcpy(outbuff, inbuff, inbuff_len);
return 0 - inbuff_len;
}
}
/* look for rle */
anchor = in_idx;
c = *in_idx++;
while(in_idx < inbuff_end
&& *in_idx == c
&& (in_idx - anchor) < 4114)
in_idx++;
/* store compression code if character is
repeated more than 2 times */
if((cnt = in_idx - anchor) > 2)
{
if(cnt <= 18) /* short rle */
{
*out_idx++ = cnt - 3;
*out_idx++ = c;
}
else /* long rle */
{
cnt -= 19;
*out_idx++ = 16 + (cnt & 0x0F);
*out_idx++ = cnt >> 4;
*out_idx++ = c;
}
ctrl_bits = (ctrl_bits << 1) | 1;
continue;
}
/* look for pattern if 2 or more characters
remain in the input buffer */
in_idx = anchor;
if((inbuff_end - in_idx) > 2)
{
/* locate offset of possible pattern
in sliding dictionary */
hash = ((((in_idx[0] & 15) << 8) | in_idx[1]) ^
((in_idx[0] >> 4) | (in_idx[2] << 4)))
& hash_len;
pat_idx = hash_tbl[hash];
hash_tbl[hash] = in_idx;
/* compare characters if we're within 4098 bytes */
if((gap = in_idx - pat_idx) <= 4098)
{
while(in_idx < inbuff_end
&& pat_idx < anchor && *pat_idx == *in_idx
&& (in_idx - anchor) < 271)
{
in_idx++;
pat_idx++;
}
/* store pattern if it is more than 2 characters */
if((cnt = in_idx - anchor) > 2)
{
gap -= 3;
if(cnt <= 15) /* short pattern */
{
*out_idx++ = (cnt << 4) + (gap & 0x0F);
*out_idx++ = gap >> 4;
}
else /* long pattern */
{
*out_idx++ = 32 + (gap & 0x0F);
*out_idx++ = gap >> 4;
*out_idx++ = cnt - 16;
}
ctrl_bits = (ctrl_bits << 1) | 1;
continue;
}
}
}
/* can't compress this character
so copy it to outbuff */
*out_idx++ = c;
in_idx = ++anchor;
ctrl_bits <<= 1;
}
/* save last load of control bits */
ctrl_bits <<= (16 - ctrl_cnt);
*ctrl_idx = ctrl_bits;
/* and return size of compressed buffer */
return out_idx - outbuff;
}
/* from C Users Journal 10/92
* DECOMPRS.C - Ross Data Compression (RDC)
* decompress function
*
* Written by Ed Ross, 1/92
*
* decompress inbuff_len bytes of inbuff into outbuff.
* return length of outbuff. */
//#include <string.h>
typedef unsigned char uchar; /* 8 bits, unsigned */
typedef unsigned int uint; /* 16 bits, unsigned */
int rdc_decompress(uchar *inbuff, uint inbuff_len, uchar *outbuff)
{
uint ctrl_bits;
uint ctrl_mask = 0;
uchar *inbuff_idx = inbuff;
uchar *outbuff_idx = outbuff;
uchar *inbuff_end = inbuff + inbuff_len;
uint cmd;
uint cnt;
uint ofs;
//uint len;
/* process each item in inbuff */
while(inbuff_idx < inbuff_end)
{
/* get new load of control bits if needed */
if((ctrl_mask >>= 1) == 0)
{
ctrl_bits = *(uint *) inbuff_idx;
inbuff_idx += 2;
ctrl_mask = 0x8000;
}
/* just copy this char if control bit is zero */
if((ctrl_bits & ctrl_mask) == 0)
{
*outbuff_idx++ = *inbuff_idx++;
continue;
}
/* undo the compression code */
cmd = (*inbuff_idx >> 4) & 0x0F;
cnt = *inbuff_idx++ & 0x0F;
switch(cmd)
{
case 0: /* short rle */
cnt += 3;
memset(outbuff_idx, *inbuff_idx++, cnt);
outbuff_idx += cnt;
break;
case 1: /* long rle */
cnt += (*inbuff_idx++ << 4);
cnt += 19;
memset(outbuff_idx, *inbuff_idx++, cnt);
outbuff_idx += cnt;
break;
case 2: /* long pattern */
ofs = cnt + 3;
ofs += (*inbuff_idx++ << 4);
cnt = *inbuff_idx++;
cnt += 16;
memcpy(outbuff_idx, outbuff_idx - ofs, cnt);
outbuff_idx += cnt;
break;
default: /* short pattern */
ofs = cnt + 3;
ofs += (*inbuff_idx++ << 4);
memcpy(outbuff_idx, outbuff_idx - ofs, cmd);
outbuff_idx += cmd;
break;
}
}
/* return length of decompressed buffer */
return outbuff_idx - outbuff;
}